/* eslint-disable no-console */
import Vue from 'vue';
import axios, { AxiosResponse } from 'axios';
import { convertKeysToCamelCase, errorReport } from '@/scripts/tools.js';

// create an axios instance
const instance = axios.create({
  baseURL: '',
  // 请求超时时间
  timeout: process.env.VUE_APP_CURRENTMODE==='release'?3000:30000,
  // 跨域携带cookie设置
  withCredentials: true,
  xsrfCookieName: '',
  headers: { 'Content-Type': 'application/json;charset=UTF-8' },
});

// 请求锁
const reqlock: {
  [lockKey: string]: unknown;
} = {};

// request interceptor
instance.interceptors.request.use(
  function (config) {
    const reqLockKey = config?.params?.reqLockKey;
    if (!reqLockKey || !reqlock[reqLockKey]) {
      reqLockKey && (reqlock[reqLockKey] = true);
      return config;
    } else {
      // request lock
      return Promise.reject();
    }
  },
  function (error) {
    // request error
    return Promise.reject(error);
  }
);

interface Response extends AxiosResponse {
  params: {
    reqLockKey: string;
    [param: string]: unknown;
  };
}
// response interceptor
instance.interceptors.response.use(
  function (response) {
    // ?.params
    if ((response as Response)?.params?.reqLockKey) {
      reqlock[reqLockKey] = false;
    }

    try {
      const { code, status_code, errorCode, errorcode } = response.data;
      if (code || status_code || errorCode || errorcode) {
        Vue.prototype.$toast('数据异常！');
        throw new Error(`接口${response.request.responseURL}报错，status_code:${response.data.code}`);
      }
      return convertKeysToCamelCase(response.data);
    } catch (error) {
      errorReport({
        name: `接口${response.request.responseURL};报错${error.name}`,
        message: error.message,
        stack: error.stack,
      });
      return convertKeysToCamelCase(response.data);
    }
  },
  function (error) {
    // response error
    return Promise.reject(error);
  }
);

/**
 * @param {String} method Request method: get、post、delete、put
 * @param {String} url Request url
 * @param {Object} data Request param
 * @returns {Promise | false}
 */
export default function (method: string, url: string, lastUrl = '', data = null, config = {}) {
  const newUrl = url + lastUrl;

  switch (method.toLowerCase()) {
    case 'post':
      return instance.post(newUrl, data, config);
    case 'get':
      return instance.get(newUrl, {
        params: data,
      });
    case 'delete':
      return instance.delete(newUrl, {
        params: data,
      });
    case 'put':
      return instance.put(newUrl, data);
    default:
      return false;
  }
}
